#include<iostream>
#pragma once 
using namespace std;
#include<string>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<cstring>
#include<netinet/in.h>
#include<arpa/inet.h>
#define DEFAULT 8081
#include<unistd.h>
#define SIZE 128
class UdpServer
{
  private:
  //  string ip;
    int port;//端口号
    int sockfd;
  public:
    UdpServer(int _port=DEFAULT)
       :port(_port) 
       ,sockfd(-1)
    {
    }
    bool InitUdpServer()
    {
      sockfd=socket(AF_INET,SOCK_DGRAM,0);
      if(sockfd<0)
      {
        cerr<<"socket error"<<endl;
        return false;
      }
      cout<<"socket  create success:sockfd:"<<sockfd<<endl;
      struct sockaddr_in local;
      memset(&local,'\0',sizeof(local));
      local.sin_family=AF_INET;
      local.sin_port=htons(port);
      //local.sin_addr.s_addr=inet_addr(ip.c_str());//将点分十进制string转为uint32_t
      local.sin_addr.s_addr=INADDR_ANY;
      if(bind(sockfd,(struct sockaddr*) &local,sizeof(local))<0)
      {
        cerr<<"bind error"<<endl;
        return false;
      }
      cout<<"bind success"<<endl;
      return true;
    }
    void start()
    {
      char buffer[SIZE];
      for(;;)
      {
        struct sockaddr_in peer;
        socklen_t len=sizeof(peer);
        //必须传入大小，输出型参数传回实际的大小
        ssize_t size=recvfrom(sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)& peer,&len);
        if(size>0)
        {
          buffer[size]=0;
          int _port=ntohs(peer.sin_port);
          string _ip=inet_ntoa(peer.sin_addr);
          cout<<_ip<<":"<<_port<<"#"<<buffer<<endl;
          string cmd=buffer;
          string result;
          if(cmd=="ls")//如果输入的是ls就把本地的ls内容刷新到客户端上
          {
            //将数据读到管道里再发出去
            int pipes[2];
            pipe(pipes);//匿名管道
            //替换
            pid_t id=fork();
            if(id==0)
            {
              //child
              close(pipes[0]);//关闭读端
              dup2(pipes[1],1);//重定向
              execl("/usr/bin/ls","ls","-a","-l","-i",nullptr);
              exit(1);
            }
            //关闭写端
            close(pipes[1]);
            char c;
            //读取管道
            while(1)
            {
              if(read(pipes[0],&c,1)>0)//读取放到c每次读一个
              {
                  result.push_back(c); 
              }
              else 
              {
                break;
              }
            }
            wait(nullptr);
          }
          string echo_msg;
          if(result.empty())
          {
            echo_msg="server get->";
            echo_msg+=buffer;
          }
          else 
          {
            echo_msg=result;
          }
          sendto(sockfd,echo_msg.c_str(),echo_msg.size(),0,(struct sockaddr*)& peer,len);
        }
        else 
        {
          cerr<<"recvfrom error"<<endl;
        }
        
      }

    }
    ~UdpServer()
    {
      if(sockfd>=0)
      {
        close(sockfd);
      }

    }
};
